# -*- coding:utf-8 -*-
import ast

from flask import render_template, request, jsonify, current_app, session
from . import car
from app import db
from app.models.business import Car, Car_Pictures as CP
from app.models.application import Car_Review as CR
from app.models.site_setting import BusinessScope as BS
from app.models.site_setting import CarAttribute, AttrBrand, AttrCarModel
from flask_login import login_required
from app.tools.permission import permission
from app.tools.log import log
from app.tools.redis_op import Operator
from app.tools.number import get_number
from app.tools.picture import save_car_picture, delete_car_picture
from app.tools.message import frontmessage
from app.tools.safe import safe_data
from app.tools.sort_redis import flat_all
import datetime
import json
from pypinyin import lazy_pinyin


@car.before_request
@login_required
@permission(['review', 'upload', 'super'])
def check_permission():  # 检查权限
    return


def check_data(data, old_car):  # 检查提交的参数
    for k, v in data.items():  # 参数完整性检查
        print k
        print v
        if v is None:
            return -1, jsonify({'state': -1, 'msg': u'参数不足'})
        if v == "" and k != 'commercial_insurance':
            return -1, jsonify({'state': -1, 'msg': u'请填写必填项'})
    if len(data['frame_number']) != 17:  # 车架号
        return 1, jsonify({'state': 1, 'msg': u'请填写正确的车架号'})
    if not old_car or data['frame_number'] != old_car.first().frame_number:
        count = Car.query.filter_by(frame_number=data['frame_number']).count()
        if count != 0:
            return 3, jsonify({'state': 3, 'msg': u'该车架号已经存在'})
    if data['new'] not in ['0', '1']:  # 新车或二手车
        return 1, jsonify({'state': 1, 'msg': u'参数错误'})
    if data['new'] == '0':
        try:  # 检查车龄格式
            float(data['age_of_car'])
        except ValueError:
            return 1, jsonify({'state': 1, 'msg': u'车龄格式错误'})
        if len(data['city'].split('/')) != 2:
            return 1, jsonify({'state': 1, 'msg': u'城市格式错误'})
        if data['specific'] not in ['true', 'false']:  # 是否是指定车型
            return 1, jsonify({'state': 1, 'msg': u'参数错误'})
        for key in ['first_licensing_date', 'annual_inspection', 'compulsory_insurance',
                    'commercial_insurance']:  # 检查各类日期的格式，年-月
            try:
                if data[key]:
                    datetime.datetime.strptime(data[key], "%Y-%m")
            except ValueError, e:
                return 1, jsonify({'state': 1, 'msg': u'时间格式错误'})
    return 0, ''


def save_car(values, number=None):  # 保存新上传的或二次编辑的车辆信息，number不为空时，表示保存二次编辑的信息
    old_car = None
    if number:  # 二次编辑
        old_car = Car.query.filter_by(number=number)
        if not old_car:
            return -1, jsonify({'state': -1, 'msg': u'车辆不存在'})
        car_number = number
    data = {}
    data['brand'] = values.get('brand')
    data['model'] = values.get('model')
    data['car_type'] = values.get('car_type')
    data['specific'] = values.get('specific')
    data['description'] = values.get('desc').replace('\n', '<br />')
    data['color'] = values.get('color')
    data['frame_number'] = values.get('frame_number')
    data['price'] = values.get('price')
    data['type_of_gearbox'] = values.get('gearbox')
    data['emission_standard'] = values.get('standard')
    data['displacement'] = values.get('displacement')
    data['number_of_seats'] = values.get('seat')
    data['city'] = values.get('city')
    data['address'] = values.get('address')
    data['contact'] = values.get('contact')
    data['phone'] = values.get('phone')
    data['new'] = values.get('new')
    if data['new'] == '0':  # 二手车有额外的字段
        data['first_licensing_date'] = values.get('licensing_date')
        data['licensing_place'] = values.get('licensing_place')
        data['mileage'] = values.get('mileage')
        data['age_of_car'] = values.get('age_of_car')
        data['annual_inspection'] = values.get('annual')
        data['compulsory_insurance'] = values.get('compulsory')
        data['commercial_insurance'] = values.get('commercial')
        data['transfer_times'] = values.get('transfer')
    state, result = check_data(data, old_car)  # 检查提交的信息
    if state != 0:
        return -1, result
    data['new'] = int(data['new'])
    data['address'] = data['city'] + '/' + data['address']
    data['city'] = data['city'].split('/')[-1]
    py = lazy_pinyin(data['city'])  # 城市拼音
    data['city_py'] = ''.join(py)
    data['specific'] = 0 if data['specific'] == 'false' else 1
    data['submission_date'] = datetime.datetime.now()
    data['state'] = 1
    data['owner_type'] = 0
    photos = {}
    photos['0'] = json.loads(values.get('car_photo'))
    if not data['new']:
        for key in ['first_licensing_date', 'annual_inspection', 'compulsory_insurance', 'commercial_insurance']:
            if data[key]:
                data[key] = datetime.datetime.strptime(data[key], "%Y-%m")
        if not data['commercial_insurance']:
            data.pop('commercial_insurance')
        photos['1'] = json.loads(values.get('check_photo'))
        photos['2'] = json.loads(values.get('other_photo'))
    data = safe_data(data)
    if old_car:  # 二次编辑
        old_car.update(data)
        car_id = old_car.first().id
        del_photos = {'0': json.loads(values.get('car_del'))}
        if not data['new']:
            del_photos['1'] = json.loads(values.get('check_del'))
            del_photos['2'] = json.loads(values.get('other_del'))
        delete_car_picture(del_photos, car_id)
    else:
        op = Operator()
        data['number'] = get_number('CY')  # 获取车辆编号
        data['owner_name'] = u'自营'
        data['model'] = ast.literal_eval(op.hget('brand', data['brand']))[0] + ' ' + data['model']
        new_car = Car(**data)
        new_car.save()
        car_id = new_car.id
        car_number = new_car.number
    save_car_picture(photos, car_id)
    return 0, car_number


@car.route('/upload/<car_type>/', methods=['GET', 'POST'])
@permission(['upload', 'super'])
def upload(car_type):  # 上传车源
    if car_type not in ['old', 'new']:
        return render_template('404.html'), 404
    values = request.values
    if values.get('submit') != 'True':
        op = Operator()
        if car_type == 'old':
            return render_template('business/car/upload_old_car.html',
                                   brand=flat_all('brand'),
                                   car_type=flat_all('car_type'),
                                   gearbox=flat_all('gearbox'),
                                   standard=flat_all('standard'),
                                   color=flat_all('color'),
                                   seat=flat_all('seat')
                                   )
        else:
            return render_template('business/car/upload_new_car.html',
                                   brand=flat_all('brand'),
                                   car_type=flat_all('car_type'),
                                   gearbox=flat_all('gearbox'),
                                   standard=flat_all('standard'),
                                   color=flat_all('color'),
                                   seat=flat_all('seat')
                                   )
    state, result = save_car(values)
    if state == 0:
        log(u'上传车辆%s' % result)
        return jsonify({'state': 0})
    return result


@car.route('/edit/', methods=['GET', 'POST'])
@permission(['upload', 'super'])
def edit():  # 修改车辆信息
    values = request.values
    number = request.values.get('number')
    if number is None:
        return render_template('404.html'), 404
    if values.get('submit') != 'True':
        result = Car.query.filter_by(number=number).first()
        if not result:
            return render_template('404.html'), 404
        photos = {'car': {}, 'check': {}, 'other': {}}
        domain = current_app.config['QINIU_DOMAIN']
        cp = CP.query.filter_by(car_id=result.id, picture_type=0).all()
        for item in cp:
            photos['car'][item.url] = domain + item.url
        if not result.new:
            cp = CP.query.filter_by(car_id=result.id, picture_type=1).all()
            for item in cp:
                photos['check'][item.url] = domain + item.url
            cp = CP.query.filter_by(car_id=result.id, picture_type=2).all()
            for item in cp:
                photos['other'][item.url] = domain + item.url
        op = Operator()
        return render_template('business/car/edit.html',
                               data=result,
                               photos=photos,
                               brand=flat_all('brand'),
                               car_type=flat_all('car_type'),
                               gearbox=flat_all('gearbox'),
                               standard=flat_all('standard'),
                               seat=flat_all('seat'),
                               color=flat_all('color')
                               )
    state, result = save_car(values, number)
    if state == 0:
        log(u'编辑车辆%s' % result)
        return jsonify({'state': 0})
    return result


@car.route('/review/list/')
@permission(['review', 'super'])
def review_list():  # 返回审批车源的界面，具体的待审车辆信息由ajax异步获取
    return render_template('business/car/review_list.html')


@car.route('/review/get_list/')
@permission(['review', 'super'])
def get_review_car():  # 获取待审车辆的信息
    values = request.values
    limit = int(values.get('limit', '10'))
    offset = int(values.get('offset', '0'))
    list_type = values.get('list_type')
    number = values.get('number')
    area = values.get('area')
    start = values.get('start')
    end = values.get('end')
    submitter = values.get('submitter')
    search_type = values.get('search_type')
    tb_name = values.get('tb_name')  # 前端页面中多个表格共用同一组搜索参数，tb_name用于标识当前是哪一个表格在使用这些参数
    if list_type is None:
        return jsonify({'state': -1, 'msg': u'参数不全'})
    try:
        start = datetime.datetime.strptime(start, '%Y-%m-%d')
        end = datetime.datetime.strptime(end, '%Y-%m-%d')
        end = end + datetime.timedelta(days=1)  # 需要加一天才可以搜索到原本的end指定的日期
    except ValueError:
        return jsonify({'state': 1, 'msg': u'参数错误'})
    result = Car.query
    kw = {}
    if tb_name == list_type and search_type != '5':  # 5代表重置搜索，即不考虑搜索条件；tb_name用于检查当前的搜索参数是否与表格相对应
        if search_type == '0':
            kw['number'] = number
        if search_type == '1' or search_type == '4':
            kw['owner_type'] = submitter
        if search_type == '2' or search_type == '4':
            if area != '':
                result = result.filter(Car.city.like('%' + area + '%'))
        if search_type == '3' or search_type == '4':
            result = result.filter(Car.submission_date.between(start, end))
    if list_type == "review":  # 待审车辆
        kw['state'] = 0
    elif list_type == "reject":  # 已拒绝车辆
        kw['state'] = 2
    else:
        return jsonify({'state': 1, 'msg': u'参数错误'})

    result = result.filter_by(**kw).order_by(db.desc(Car.submission_date)).paginate(offset / limit + 1, limit, False)
    count = result.total
    op = Operator()
    data = []
    for item in result.items:
        data.append({
            'number': item.number,
            'brand': ast.literal_eval(op.hget('brand', item.brand))[0],
            'model': item.model,
            'price': item.price,
            'owner': item.owner_name,
            'phone': item.phone,
            'car_type': u'新车' if item.new else u'二手车',
            'area': item.city,
            'submission_date': item.submission_date.strftime("%Y-%m-%d %H:%M:%S"),
        })
    json = {'total': count, 'rows': data}
    return jsonify(json)


@car.route('/details/')
def detail():  # 车辆详情页
    number = request.values.get('number')
    if number is None:
        return render_template('404.html'), 404
    result = Car.query.filter_by(number=number).first()
    photos = {'car': [], 'check': [], 'other': []}
    cp = CP.query.filter_by(car_id=result.id, picture_type=0).all()
    domain = current_app.config['QINIU_DOMAIN']
    for item in cp:
        photos['car'].append(domain + item.url)
    if not result.new:
        cp = CP.query.filter_by(car_id=result.id, picture_type=1).all()
        for item in cp:
            photos['check'].append(domain + item.url)
        cp = CP.query.filter_by(car_id=result.id, picture_type=2).all()
        for item in cp:
            photos['other'].append(domain + item.url)
    op = Operator()
    kw = {'data': result, 'photos': photos, 'op': op}
    if result.state == 2:
        cr = CR.query.filter_by(cid=result.id).first()
        reason = u'无'
        if cr:
            reason = cr.reason
        kw['reason'] = reason
    return render_template('business/car/detail.html', eval=ast.literal_eval, **kw)


@car.route('/review/pass/', methods=['GET', 'POST'])
@permission(['review', 'super'])
def review_pass():  # 通过车辆审批
    number = request.values.get('number')
    if number is None:
        return jsonify({"state": -1, 'msg': u'参数不足'})
    review_car = Car.query.filter_by(number=number, state=0).first()
    if not review_car:
        return jsonify({"state": 2, 'msg': u'对象不存在'})
    else:
        review_car.state = 1
        # 用户上传的车辆城市不在业务范围内的时候，添加该城市
        op = Operator()
        city_list = op.hgetall('city_list')
        if review_car.city_py[0] in city_list.keys() and review_car.city_py in ast.literal_eval(city_list[review_car.city_py[0]]).keys():
            pass
        else:
            if not review_car.city_py[0] in city_list.keys():
                op.hset('city_list', review_car.city_py[0], {review_car.city_py: review_car.city})
            else:
                city_list = op.hgetall('city_list')
                dist = ast.literal_eval(city_list.get(review_car.city_py[0]))
                dist[review_car.city_py] = review_car.city
                op.hset('city_list', review_car.city_py[0], dist)
            BS(city=review_car.city)
        cr = CR(cid=review_car.id, reviewer_id=session['sid'], state=0, time=datetime.datetime.now())
        review_car.save()
        cr.save()
        frontmessage('car',
                     u'您提交的车辆 <a target="_blank" href="/detail/%(id)s.html">%(car)s</a> \
                    已经通过审核' % {'id': review_car.id, 'car': review_car.model},
                     review_car.owner_id)
        log(u'通过车辆%s的审批' % review_car.number)
        db.session.commit()
        return jsonify({"state": 0})


@car.route('/review/reject/', methods=['GET', 'POST'])
@permission(['review', 'super'])
def review_reject():  # 拒绝车辆审批
    number = request.values.get('number')
    reason = request.values.get('reason')
    if number is None or reason is None:
        return jsonify({'state': -1, 'msg': u'参数不全'})
    if reason == "":
        return jsonify({'state': -1, 'msg': u'请填写拒绝原因'})
    review_car = Car.query.filter_by(number=number, state=0).first()
    if not review_car:
        return jsonify({'state': 2, 'msg': u'对象不存在'})
    else:
        review_car.state = 2
        cr = CR(cid=review_car.id, reviewer_id=session['sid'], state=1, reason=safe_data(reason),
                time=datetime.datetime.now())
        review_car.save()
        cr.save()
        frontmessage('car', u'您提交的车辆%s未能通过审核，拒绝原因：%s' % (review_car.id, reason), review_car.owner_id)
        log(u'拒绝车辆%s' % review_car.number)
        return jsonify({"state": 0})


@car.route('/sale/list/')
@permission(['upload', 'super'])
def sale_list():  # 返回在售车辆的页面，具体车辆数据由ajax异步获取
    return render_template('business/car/sale.html', sale=True)


@car.route('/sale/get_list/')
@permission(['upload', 'super'])
def get_sale_car():  # 获取在售车辆
    values = request.values
    limit = int(values.get('limit', '10'))
    offset = int(values.get('offset', '0'))
    list_type = values.get('list_type')
    number = values.get('number')
    area = values.get('area')
    start = values.get('start')
    end = values.get('end')
    submitter = values.get('submitter')
    search_type = values.get('search_type')
    tb_name = values.get('tb_name')
    if list_type is None:
        return jsonify({'state': -1, 'msg': u'参数不全'})
    try:
        start = datetime.datetime.strptime(start, '%Y-%m-%d')
        end = datetime.datetime.strptime(end, '%Y-%m-%d')
        end = end + datetime.timedelta(days=1)
    except ValueError:
        return jsonify({'state': 1, 'msg': u'参数错误'})
    result = Car.query
    kw = {}
    if tb_name == list_type and search_type != '5':
        if search_type == '0':
            kw['number'] = number
        if search_type == '1' or search_type == '4':
            kw['owner_type'] = submitter
        if search_type == '2' or search_type == '4':
            if area != '':
                result = result.filter(Car.city.like('%' + area + '%'))
        if search_type == '3' or search_type == '4':
            result = result.filter(Car.submission_date.between(start, end))
    if list_type == "on_sale":
        kw['state'] = 1
    elif list_type == "sold":
        kw['state'] = 3
    elif list_type == "delete":
        kw['state'] = 4
    else:
        return jsonify({'state': 1, 'msg': u'参数错误'})
    result = result.filter_by(**kw).order_by(db.desc(Car.submission_date)).paginate(offset / limit + 1, limit, False)
    count = result.total
    op = Operator()
    data = []
    for item in result.items:
        data.append({
            'number': item.number,
            'brand': ast.literal_eval(op.hget('brand', item.brand))[0],
            'model': item.model,
            'price': item.price,
            'owner': item.owner_name,
            'phone': item.phone,
            'car_type': u'新车' if item.new else u'二手车',
            'area': item.city,
            'submission_date': item.submission_date.strftime("%Y-%m-%d %H:%M:%S"),
        })
    json = {'total': count, 'rows': data}
    return jsonify(json)


@car.route('/sale/on_sale/', methods=['GET', 'POST'])
def sale_on_sale():  # 置为在售
    number = request.values.get('number')
    if number is None:
        return jsonify({"state": -1, 'msg': u'参数不全'})
    sale_car = Car.query.filter_by(number=number).first()
    if not sale_car:
        return jsonify({"state": 2, 'msg': u'对象不存在'})
    if sale_car.state != 3:
        return jsonify({"state": 4, 'msg': u'对象状态错误'})
    else:
        sale_car.state = 1
        sale_car.save()
        log(u'将车辆%s置为在售状态' % sale_car.number)
        return jsonify({"state": 0})


@car.route('/sale/delete/', methods=['GET', 'POST'])
def sale_delete():  # 下架
    number = request.values.get('number')
    if number is None:
        return jsonify({"state": -1, 'msg': u'参数不全'})
    sale_car = Car.query.filter_by(number=number).first()
    if not sale_car:
        return jsonify({"state": 2, 'msg': u'对象不存在'})
    if sale_car.state not in [1, 3]:
        return jsonify({"state": 4, 'msg': u'对象状态错误'})
    else:
        sale_car.state = 4
        sale_car.save()
        log(u'删除车辆%s' % sale_car.number)
        return jsonify({"state": 0})


@car.route('/sale/sold/', methods=['GET', 'POST'])
def sale_sold():  # 置为已售
    number = request.values.get('number')
    if number is None:
        return jsonify({"state": -1, 'msg': u'参数不足'})
    sale_car = Car.query.filter_by(number=number).first()
    if not sale_car:
        return jsonify({"state": 2, 'msg': u'对象不存在'})
    if sale_car.state != 1:
        return jsonify({"state": 4, 'msg': u'对象状态错误'})
    else:
        sale_car.state = 3
        sale_car.save()
        log(u'将车辆%s置为已售状态' % sale_car.number)
        return jsonify({"state": 0})
